﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using BestTrader.Cms.Core.Extensions;
using BestTrader.Cms.Core.Helper;
using BestTrader.Cms.IServices;
using BestTrader.Cms.Models;
using BestTrader.Cms.UserCenter.Validation;
using BestTrader.Cms.ViewModels;
using FluentValidation.Results;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;

namespace BestTrader.Cms.Admin.Controllers
{
    public class AccountController : Controller
    {
        private readonly IManagerService _service;
        private readonly IManagerRoleService _roleService;

        public AccountController(IManagerService service, IManagerRoleService roleService)
        {
            _service = service;
            _roleService = roleService;
        }

        #region 登录

        /// <summary>
        /// 用户登录
        /// </summary>
        public IActionResult Index(string returnUrl)
        {
            if (returnUrl.IsNullOrWhiteSpace())
            {
                returnUrl = "/";
            }
            ViewData["ReturnUrl"] = returnUrl;
            return View();
        }

        [HttpPost, ValidateAntiForgeryToken, Route("Account/SignIn")]
        public async Task<string> SignInAsync(LoginModel model)
        {
            var result = new TableDataResult<Manager>()
            {
                Success = false
            };
            #region 判断验证码
            //if (!ValidateCaptchaCode(model.CaptchaCode))
            //{
            //    result.ResultCode = ResultCodeAddMsgKeys.SignInCaptchaCodeErrorCode;
            //    result.ResultMsg = ResultCodeAddMsgKeys.SignInCaptchaCodeErrorMsg;
            //    return JsonHelper.ObjectToJSON(result);
            //}
            #endregion
            #region 判断错误次数
            //var ErrorTimes = HttpContext.Session.GetInt32(ManagerSignInErrorTimes);
            //if (ErrorTimes == null)
            //{
            //    HttpContext.Session.SetInt32(ManagerSignInErrorTimes, 1);
            //    ErrorTimes = 1;
            //}
            //else
            //{
            //    HttpContext.Session.SetInt32(ManagerSignInErrorTimes, ErrorTimes.Value + 1);
            //}
            //if (ErrorTimes > MaxErrorTimes)
            //{
            //    result.ResultCode = ResultCodeAddMsgKeys.SignInErrorTimesOverTimesCode;
            //    result.ResultMsg = ResultCodeAddMsgKeys.SignInErrorTimesOverTimesMsg;
            //    return JsonHelper.ObjectToJSON(result);
            //}
            #endregion
            #region 再次属性判断
            LoginModelValidation validation = new LoginModelValidation();
            ValidationResult results = validation.Validate(model);
            if (!results.IsValid)
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonModelStateInvalidCode;
                result.ResultMsg = results.ToString("||");
            }
            #endregion

            model.Ip = HttpContext.GetClientUserIp();
            var manager = _service.SignIn(model);
            if (manager == null)
            {
                result.ResultCode = ResultCodeAddMsgKeys.SignInPasswordOrUserNameErrorCode;
                result.ResultMsg = ResultCodeAddMsgKeys.SignInPasswordOrUserNameErrorMsg;
            }
            else if (manager.IsLock)
            {
                result.ResultCode = ResultCodeAddMsgKeys.SignInUserLockedCode;
                result.ResultMsg = ResultCodeAddMsgKeys.SignInUserLockedMsg;
            }
            else if (manager.State != 1)
            {
                result.ResultCode = ResultCodeAddMsgKeys.LoginStateExceptionCode;
                result.ResultMsg = ResultCodeAddMsgKeys.LoginStateExceptionMsg;
            }
            else
            {
                result.Success = true;
                result.Data = manager;

                // [ASP.NET Core [4]: Authentication(笔记）](https://www.cnblogs.com/fuyouchen/p/9560120.html)
                var claims = new List<Claim>
                {

                    new Claim(ClaimTypes.Name, manager.UserName),
                    //new Claim(ClaimTypes.MobilePhone, manager.Mobile),
                    new Claim(ClaimTypes.Role,manager.RoleId.ToString()),
                    //new Claim(ClaimTypes.Email, manager.Email),
                    //new Claim("NickName",manager.NickName),
                    new Claim("UserId", manager.Id.ToString()),
                    new Claim("RealName",manager.RealName),
                    new Claim("State", manager.State.ToString()),
                    new Claim("LoginCount",manager.LoginCount.ToString()),
                    new Claim("LoginLastIp",manager.LoginLastIp),
                    new Claim("LoginLastTime",manager.LoginLastTime?.ToString("yyyy-MM-dd HH:mm:ss")),
                };

                var claimsIdentity = new ClaimsIdentity(
                    claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var user = new ClaimsPrincipal(claimsIdentity);
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme, user);
            }
            return JsonHelper.ObjectToJSON(result);
        }

        [Route("Account/SignOut")]
        public async Task<IActionResult> SignOutAsync()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return RedirectToAction("Index");
        }

        #endregion

        #region 密码修改
        [HttpGet]
        public IActionResult EditPassword()
        {
            ViewData["UserName"] = User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;
            ViewData["UserId"] = User.Claims.FirstOrDefault(x => x.Type == "UserId")?.Value;
            return View();
        }

        [HttpPost]
        public string EditPassword(PasswordModel model)
        {
            var result = new BooleanResult();

            PasswordModelValidation validation = new PasswordModelValidation();

            ValidationResult results = validation.Validate(model);
            if (results.IsValid)
            {
                result = _service.EditPassword(model);
            }
            else
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonModelStateInvalidCode;
                result.ResultMsg = results.ToString("||");
            }
            return JsonHelper.ObjectToJSON(result);
        }

        #endregion

    }
}